import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.*;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 38917
 * Date: 2025-03-18
 * Time: 17:29
 */
public class TCPEchoSever {
    //
    private final ServerSocket socket;
    //线程池
    private final ThreadPoolExecutor executor = new ThreadPoolExecutor(4,8,1,
            TimeUnit.MINUTES, new ArrayBlockingQueue<>(1024),Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy());
    //
    public TCPEchoSever(int port) throws IOException {
        socket = new ServerSocket(port);
    }
    //启动服务器
    protected void start() throws IOException {
        System.out.println("服务器启动");
        while (true){
            //将服务器和客户端连接
            //accept()有阻塞效果，等待客户端建立联系
            Socket clientSocket = socket.accept();
            //每与一个客户端建立连接，都创建一个线程来执行客户端的请求
            executor.execute(() -> {
                try {
                    processConnection(clientSocket);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
        }
    }
    //
    public void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("[%s:%d] 服务器上线\n",clientSocket.getInetAddress(),clientSocket.getPort());
            //inputStream从网卡读数据
        try(InputStream inputStream = clientSocket.getInputStream();
            //OutputStream往网卡写数据
            OutputStream outputStream = clientSocket.getOutputStream()) {
            //从网卡读数据
            //byte[] array = new byte[1024];int ret = inputStream.read(array);
            PrintWriter printWriter = new PrintWriter(outputStream);
            Scanner scanner = new Scanner(inputStream);
            while (true){
                //读取完毕，当客户端下线的时候产生
                //在用户输入之前，hasNext()有阻塞效果
                //当客户端断开连接时，scanner.hasNext()返回false并中断循环
                if (!scanner.hasNext()){
                    System.out.printf("[%s:%d] 客户端下线\n",clientSocket.getInetAddress(),clientSocket.getPort());
                    break;
                }
                //1.读取请求并解析
                //用户传过来的请求必须带有空白符，没有的话就会阻塞
                String request = scanner.next();
                //2.计算响应
                String response = process(request);
                //3.返回响应
                //outputStream.write(response.getBytes(),0,response.getBytes().length);//这个方式不方便添加空白符
                //通过PrintWriter来封装outputStream
                //添加\n
                printWriter.println(response);
                //刷新缓冲区
                printWriter.flush();
                //打印日志
                System.out.printf("[%s:%d] request:%s,response:%s\n",clientSocket.getInetAddress(),
                        clientSocket.getPort(),request,response);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            clientSocket.close();
        }
    }
    //计算响应
    protected String process(String request) {
        return request;
    }
    //
    public static void main(String[] args) throws IOException {
        TCPEchoSever sever = new TCPEchoSever(9090);
        sever.start();
    }
}



























